<template>
  <!-- 检索栏 -->
  <a-form class="smart-query-form" :model="queryParams" ref="queryRef" layout="inline" v-show="showSearch"
    :label-col="{ span: 5 }" :wrapper-col="{ span: 19 }">
    <a-row class="smart-query-form-row">
      <a-form-item label="流程名称" name="processName" class="smart-query-form-item">
        <a-input v-model:value="queryParams.processName" placeholder="请输入流程名称" allowClear @pressEnter="handleQuery" />
      </a-form-item>
      <a-form-item label="流程标识" name="processKey" class="smart-query-form-item">
        <a-input v-model:value="queryParams.processKey" placeholder="请输入流程标识" allowClear @pressEnter="handleQuery" />
      </a-form-item>
      <a-form-item label="流程分类" name="category" class="smart-query-form-item">
        <a-select v-model:value="queryParams.category" placeholder="流程分类" allowClear style="width: 240px">
          <a-select-option v-for="item in flowCategory" :key="item.code" :value="item.code">
            {{ item.name }}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="状态" name="state" class="smart-query-form-item">
        <a-select v-model:value="state" size="small" allowClear style="width: 100px;" placeholder="请选择状态">
          <a-select-option :value="'active'">激活</a-select-option>
          <a-select-option :value="'suspended'">挂起</a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item class="smart-query-form-item">
        <a-button-group>
          <a-button type="primary" @click="handleQuery" v-privilege="'flow:flow_model:list'">
            <template #icon>
              <SearchOutlined />
            </template>
            查询
          </a-button>
          <a-button @click="resetQuery" v-privilege="'flow:flow_model:list'">
            <template #icon>
              <ReloadOutlined />
            </template>
            重置
          </a-button>
        </a-button-group>
      </a-form-item>
    </a-row>
  </a-form>

  <a-card size="small" :bordered="false" :hoverable="true">
    <a-row class="smart-table-btn-block">
      <div class="smart-table-operate-block">
        <a-button type="primary" danger :disabled="selectedRowKeyList.length === 0" @click="handleDelete"
          v-privilege="['flowable:deploy:remove']">
          <template #icon>
            <DeleteOutlined />
          </template>
          删除
        </a-button>
      </div>
      <div class="smart-table-setting-block">
        <TableOperator v-model="columns" :refresh="getList" />
      </div>
    </a-row>

    <a-table size="small" :dataSource="deployList" :pagination="false" rowKey="deploymentId"
      :rowSelection="{ selectedRowKeys: selectedRowKeyList, onChange: handleSelectionChange }">
      <a-table-column title="流程名称" align="center" :ellipsis="true">
        <template #default="{ record }">
          <a-button type="link" @click="handleProcessView(record)">
            {{ record.processName }}
          </a-button>
        </template>
      </a-table-column>
      <a-table-column title="流程标识" dataIndex="processKey" align="center" />
      <a-table-column title="流程分类" dataIndex="category" align="center">
        <template #default="{ record }">
          {{ categoryFormat(record) }}
        </template>
      </a-table-column>
      <a-table-column title="流程版本" align="center">
        <template #default="{ record }">
          <a-tag size="small">v{{ record.version }}</a-tag>
        </template>
      </a-table-column>
      <a-table-column title="流程状态" align="center">
        <template #default="{ record }">
          <a-tag :color="record.suspended ? 'warning' : 'success'">
            {{ record.suspended ? '挂起' : '激活' }}
          </a-tag>
        </template>
      </a-table-column>
      <a-table-column title="部署时间" dataIndex="deploymentTime" align="center" width="180">
        <template #default="{ record }">
          <span>{{ parseTime(record.deploymentTime) }}</span>
        </template>
      </a-table-column>
      <a-table-column title="操作" align="center" width="280">
        <template #default="{ record }">
          <a-space>
            <a-button type="link" size="small" v-if="!record.suspended" @click="handleChangeState(record, 'suspended')"
              v-privilege="['flowable:deploy:status']">
              <template #icon>
                <PauseOutlined />
              </template>
              挂起
            </a-button>
            <a-button type="link" size="small" v-if="record.suspended" @click="handleChangeState(record, 'active')"
              v-privilege="['flowable:deploy:status']">
              <template #icon>
                <PlayCircleOutlined />
              </template>
              激活
            </a-button>
            <a-button type="link" size="small" @click="handlePublish(record)"
              v-privilege="['flowable:deploy:publishList']">
              <template #icon>
                <HistoryOutlined />
              </template>
              版本管理
            </a-button>
            <a-button type="link" size="small" @click="handleDelete(record)" v-privilege="['flowable:deploy:remove']">
              <template #icon>
                <DeleteOutlined />
              </template>
              删除
            </a-button>
          </a-space>
        </template>
      </a-table-column>
    </a-table>

    <div class="smart-query-table-page">
      <a-pagination showSizeChanger showQuickJumper show-less-items :pageSizeOptions="PAGE_SIZE_OPTIONS"
        :defaultPageSize="queryForm.pageSize" v-model:current="queryForm.pageNum" v-model:pageSize="queryForm.pageSize"
        :total="total" @change="getList" @showSizeChange="getList" :show-total="(total) => `共${total}条`" />
    </div>
  </a-card>

  <!-- 流程查看界面-->
  <a-modal :title="processView.title" v-model:open="processView.open" width="80%" :footer="null" :destroyOnClose="true">
    <WorkflowView :bpmnXml="processView.bpmnXml" style="height: 90vh" />
  </a-modal>

  <!-- 版本管理 -->
  <a-modal title="版本管理" v-model:open="publish.open" width="80%" :footer="null" :destroyOnClose="true">
    <a-table :dataSource="publish.dataList" :pagination="false" :scroll="{ y: 'calc(100vh - 300px)' }">
      <a-table-column title="流程名称" align="center" :ellipsis="true">
        <template #default="{ record }">
          <a-button type="link" @click="handleProcessView(record)">
            {{ record.processName }}
          </a-button>
        </template>
      </a-table-column>
      <a-table-column title="流程标识" dataIndex="processKey" align="center" :ellipsis="true" />
      <a-table-column title="流程版本" align="center">
        <template #default="{ record }">
          <a-tag size="small">v{{ record.version }}</a-tag>
        </template>
      </a-table-column>
      <a-table-column title="状态" align="center">
        <template #default="{ record }">
          <a-tag :color="record.suspended ? 'warning' : 'success'">
            {{ record.suspended ? '挂起' : '激活' }}
          </a-tag>
        </template>
      </a-table-column>
      <a-table-column title="操作" align="center" width="200">
        <template #default="{ record }">
          <a-space>
            <a-button type="link" size="small" v-if="!record.suspended" @click="handleChangeState(record, 'suspended')"
              v-privilege="['workflow:deploy:status']">
              <template #icon>
                <PauseOutlined />
              </template>
              挂起
            </a-button>
            <a-button type="link" size="small" v-if="record.suspended" @click="handleChangeState(record, 'active')"
              v-privilege="['workflow:deploy:status']">
              <template #icon>
                <PlayCircleOutlined />
              </template>
              激活
            </a-button>
            <a-button type="link" size="small" @click="handleDelete(record)" v-privilege="['workflow:deploy:remove']">
              <template #icon>
                <DeleteOutlined />
              </template>
              删除
            </a-button>
          </a-space>
        </template>
      </a-table-column>
    </a-table>
    <div class="smart-query-table-page">
      <a-pagination showSizeChanger showQuickJumper show-less-items :pageSizeOptions="PAGE_SIZE_OPTIONS"
        :defaultPageSize="publishQueryForm.pageSize" v-model:current="publishQueryForm.pageNum" v-model:pageSize="publishQueryForm.pageSize"
        :total="publishTotal" @change="getPublishList" @showSizeChange="getPublishList" :show-total="(publishTotal) => `共${publishTotal}条`" />
    </div>
  </a-modal>
</template>

<script setup name="Deploy">
import { ref, reactive, toRefs } from "vue";
import { message, Modal } from 'ant-design-vue';
import {
  SearchOutlined,
  ReloadOutlined,
  DeleteOutlined,
  PauseOutlined,
  PlayCircleOutlined,
  HistoryOutlined
} from '@ant-design/icons-vue';
import { deployApi } from "/@/api/business/flowable/deploy";
import { categoryApi } from "/@/api/business/flowable/category";
import WorkflowView from "/@/components/business/flowable/bpmn/view.vue";
import InitBPMNXml from '/@/assets/bpmn/empty.bpmn20.xml?raw';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { parseTime } from "/@/components/common/util";
import TableOperator from '/@/components/support/table-operator/index.vue';
import _ from 'lodash';

const deployList = ref([]);
const open = ref(false);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const flowCategory = ref([]);
const state = ref('');

const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    definitionId: null,
    processName: null,
    processKey: null,
    category: null,
    version: null,
    deploymentId: null,
    suspended: null,
    deploymentTime: null
  },
  rules: {},
  processView: {
    title: '',
    open: false,
    modelId: undefined,
    bpmnXml: ''
  },
  publishQueryParams: {
    pageNum: 1,
    pageSize: 10,
    processKey: ""
  },
  publish: {
    open: false,
    loading: false,
    dataList: []
  },
  publishTotal: 0
});
// 查询表单form
const queryForm = reactive(_.cloneDeep(data.queryParams));

const publishQueryForm = reactive(_.cloneDeep(data.publishQueryParams));

const { queryParams, form, rules, processView, publishQueryParams, publish, publishTotal } = toRefs(data);

/** 查询流程部署列表 */
async function getList() {
  SmartLoading.show()
  try {
    let deploy = await deployApi.listDeploy(queryForm)
    deployList.value = deploy.data.rows;
    total.value = deploy.data.total;
  } catch (e) {
    smartSentry.captureError(e)
  } finally {
    SmartLoading.hide()
  }
}

// 取消按钮
function cancel() {
  open.value = false;
  reset();
}

// 表单重置
function reset() {
  form.value = {
    definitionId: null,
    processName: null,
    processKey: null,
    category: null,
    version: null,
    deploymentId: null,
    suspended: null,
    deploymentTime: null
  };
  // proxy.resetForm("deployRef");
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  if (state.value) {
    queryParams.value.suspended = state.value === 'active' ? false : state.value === 'suspended' ? true : null;
  } else {
    queryParams.value.suspended = null;
  }
  getList();
}

/** 重置按钮操作 */
function resetQuery() {
  // proxy.resetForm("queryRef");
  handleQuery();
}

// 多选框选中数据
function handleSelectionChange(selectedRowKeys) {
  ids.value = selectedRowKeys;
  single.value = selectedRowKeys.length !== 1;
  multiple.value = !selectedRowKeys.length;
  selectedRowKeyList.value = selectedRowKeys;
}

// 选择表格行
const selectedRowKeyList = ref([]);

function onSelectChange(selectedRowKeys) {
  selectedRowKeyList.value = selectedRowKeys;
}

/** 查看流程图 */
async function handleProcessView(row) {
  const definitionId = row.definitionId;
  try {
    let deploy = await deployApi.getBpmnXml(definitionId)
    let xml = '';
    if (deploy.data && deploy.data !== '') {
      xml = deploy.data.replaceAll('\\"', '"').replaceAll('\\n', '');
    } else {
      xml = InitBPMNXml;
    }
    processView.value = {
      modelId: definitionId,
      open: true,
      title: '流程图',
      bpmnXml: xml
    };
  } catch (e) {
    smartSentry.captureError(e)
  }
}

async function getPublishList() {
  try {
    let response = await deployApi.publishList(publishQueryForm)
    publish.value = {
      dataList: response.data.rows,
      open: true,
      loading: false
    };
    publishTotal.value = response.data.total;
  } catch (e) {
    smartSentry.captureError(e)
  }
}

function handlePublish(row) {
  publishQueryForm.processKey = row.processKey;
  getPublishList();
}

/** 挂起/激活流程 */
async function handleChangeState(row, state) {
  const params = {
    definitionId: row.definitionId,
    processKey: row.processKey,
    state: state
  };
  try {
    let res = await deployApi.changeState(params)
    if (res.ok) {
      message.success("操作成功");
    } else {
      message.error("操作失败")
      return
    }

    publishQueryParams.value.processKey = row.processKey;
    getList();
    if (data.publish.open) {
      try {
        let response = await deployApi.publishList(publishQueryParams.value)
        publish.value = {
          dataList: response.data.rows,
          open: data.publish.open,
          loading: false
        };
        publishTotal.value = response.data.total;
      } catch (e) {
        smartSentry.captureError(e)
      }
    }
  } catch (e) {
    smartSentry.captureError(e)
  }

}

/** 删除按钮操作 */
function handleDelete(row) {
  let _definitionIds = selectedRowKeyList.value
  if (row.deploymentId) {
    _definitionIds = row.deploymentId
  }
  Modal.confirm({
    title: '确认',
    content: `是否确认删除选中的流程部署？`,
    onOk() {
      if (deleteDeploy(_definitionIds)) {
        // 返回删除成功后，判断是不是批量删除，如果是的话清空已选中的键
        if(!row.deploymentId) {
          selectedRowKeyList.value = []
        }
      }
    }
  });
}

async function deleteDeploy(definitionIds) {
  try {
    await deployApi.delDeploy(definitionIds)
    getList()
    if (data.publish.open) {
      let response = await deployApi.publishList(publishQueryParams.value)
      publish.value = {
        dataList: response.data.rows,
        open: data.publish.open,
        loading: false
      };
      publishTotal.value = response.data.total;
    }
    message.success("删除成功");
    return true
  } catch (e) {
    smartSentry.captureError(e)
    return false
  }
}

/**
 * 翻译分类编码
 */
function categoryFormat(row) {
  return flowCategory.value.find(k => k.code === row.category)?.name ?? '';
}

/**
 * 获取流程分类
 */
async function getFlowCategory() {
  try {
        // 这里强制搜索大小为65536，否则查询的结果只返回默认的前10个
    let category = await categoryApi.listCategory({pageSize: 65536})
    flowCategory.value = category.data.rows;
  } catch (e) {
    smartSentry.captureError(e)
  }
}

getList();
getFlowCategory();
</script>

<style scoped>
.mb8 {
  margin-bottom: 8px;
}
</style>
